package com.shujia

import scala.collection.mutable.ListBuffer

object Demo11List {
  def main(args: Array[String]): Unit = {
    /**
     * List：有序的、不可变的（属于immutable包中），元素可以重复
     * 如果将泛型指定为Any => 让元素为任意类型
     */
    // 定义一个List
    val list: List[Int] = List[Int](1, 2, 0, 3, 4, 5, 6, 7, 7, 8, -1, -2, -8, -9)

    // 取元素
    println(list(3))

    //    list(3) = 44
    println(list)

    // 常见的操作
    println(list.head) // 取第一个元素
    println(list.tail) // 取除第一个元素以外的元素
    println(list.max) // 取除最大的元素
    println(list.min) // 取除最小的元素
    println(list.size) // 返回list的大小
    println(list.length) // 返回list的长度
    println(list.take(3)) // 取3个元素
    println(list.sum) // 累加
    println(list.isEmpty) // 判断是否为空
    println(list.distinct) // 去重
    println(list.reverse) // 反转
    println(list.mkString("|")) // 按照指定的分割符拼接list中的每一个元素
    // list是不可以改变的 所以调用各种方法后不会对自身造成修改
    println(list)

    // 常见的一些方法

    /**
     * map方法：接收一个函数f：参数类型为Int（list中每个元素的类型是Int），返回值类型由自己定义
     * 会将list中的每一个元素依次传递给函数f，最后返回一个新的list
     */

    // 将里面的每个元素做一次平方
    val list2: List[Double] = list.map(Math.pow(_, 2))
    val list3: List[Int] = list.map(i => i * i)

    println(list2)
    println(list3)

    /**
     * flatMap方法：接收一个函数f：参数类型为String（list中每个元素的类型是String），返回值类型为集合类的类型
     * 会将list中的每一个元素依次传递给函数f，最后返回一个新的list
     * 最后会将返回的"数据容器"进行展开
     */
    val words: List[String] = List("java,scala,python", "java,scala,python", "java,scala,python", "Hadoop,Hive,HBase", "Spark,Flink,MapReduce")

    words.map(str => {
      val array: Array[String] = str.split(",")
      array.toList
    }).foreach(println)

    // 将array进行了展开
    val word: List[String] = words.flatMap(str => {
      val array: Array[String] = str.split(",")
      array
    })

    println(word)

    /**
     * foreach方法：接收一个函数f：参数类型为String（list中每个元素的类型是String），返回值类型为Unit
     * 会将list中的每一个元素依次传递给函数f
     * 同map方法最大的区别在于 有无返回值
     */
    word.foreach(println)

    /**
     * groupBy方法：指定一个分组字段 按照什么进行分组
     * 最后返回一个Map（K-V格式） 会以指定的分组字段作为Key 属于同一组的所有的元素（构造成List）作为Value
     */
    println(word.groupBy(w => w))
    println("*" * 100)

    /**
     * filter方法：接收一个函数f：参数类型为Int（list中每个元素的类型是Int），返回值类型为Boolean类型
     * 会将list中的每一个元素依次传递给函数f，会根据函数f返回的Boolean值进行过滤
     * 为true即保留，为false即过滤
     */
    println(list)

    // 将奇数过滤出来
    list.filter(i => {
      var flag: Boolean = false
      if (i % 2 == 1) {
        flag = true
      }
      flag
    }).foreach(println)
    // 简化的写法
    list.filter(_ % 2 == 1).foreach(println)


    /**
     * sorted：对list按照从小到大的顺序进行排序 返回一个新的list
     */
    println(list.sorted)

    /**
     * sortWith：接收一个函数f：参数有两个（分别是Int、Int类型），返回值类型为Boolean
     * 指定一个排序规则
     */
    println(list)
    // 降序排列
    println(list.sortWith((i, j) => {
      i > j
    }))
    // 按照绝对值大小进行降序排序
    println(list.sortWith((i, j) => {
      Math.abs(i) > Math.abs(j)
    }))

    val tupleList: List[(Int, Int)] = List((1, 2), (3, 5), (2, 4))
    println(tupleList.sortWith((t1, t2) => {
      t1._2 > t2._2
    }))

    /**
     * sortBy：指定一个字段进行排序
     * 接收一个函数f：参数是Tuple类型，返回值类型自定
     * 根据函数f返回的值进行排序
     */

    println(tupleList.sortBy(t => {
      t._2
    }))

    // 可变的List
    val listBuffer: ListBuffer[Int] = ListBuffer[Int](1, 2, 3, 4, 5, 6, 6, 7, 0, 9, 8)
    println(listBuffer)

    // 查
    println(listBuffer(7))
    println(listBuffer.indexOf(0))

    // 增
    listBuffer.append(10, 11, 12)
    println(listBuffer)
    listBuffer.+=(13, 14, 15)
    println(listBuffer)
    listBuffer.insert(14, 122, 123)
    println(listBuffer)

    // 删
    listBuffer.remove(9, 2)
    println(listBuffer)
    listBuffer.-=(0)
    println(listBuffer)


    // 改
    listBuffer(6) = 66
    println(listBuffer)
    listBuffer.update(6, 666)
    println(listBuffer)


  }


}
